<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2024/3/20
 * Time: 11:46
 */

namespace app\queue\videopart;

use app\common\lib\Ai\OpenApi;
use app\common\lib\Common;
use app\common\lib\Guzzle;
use app\common\lib\Puppeteer;
use app\common\lib\RedisQueue;
use app\common\lib\TencentAsr;
use app\common\lib\TencentIvld;
use app\exception\IndexException;
use app\model\redis\RedisQueueModel;
use app\model\user\UserPromotionVideoModel;
use app\model\video\AsyncUploadVideoIvldModel;
use support\Cache;
use Webman\RedisQueue\Consumer;
use app\common\lib\TencentCos;

class AsyncVideoPart  implements Consumer
{
    // 要消费的队列名
    public $queue = 'asyncVideoPart';

    // 连接名，对应 plugin/webman/redis-queue/redis.php 里的连接`
    public $connection = 'default';

    protected $resultData = [];

    // 消费
    public function consume($data)
    {
        Common::initQueueConfig();

        $queue = RedisQueueModel::getInstance()->find($data['queueid']);
        $queue->exec_time = date('Y-m-d H:i:s');
        $queue->save();

        try{

            $result = $this->handle($data);

            RedisQueue::getInstance()->saveQueue($this->queue,$data,$result);
        }catch (\Throwable $e){
            RedisQueue::getInstance()->saveQueue($this->queue,$data,['error'=>$e->getMessage()]);
            Common::queueExecptionReport($queue,$data,$e);
        }
    }

    protected function handle($data)
    {
        $requestId = $data['requestid'];
        $video = UserPromotionVideoModel::getInstance()->find($data['id']);
        if(!empty($video['video_content'])){
            try{
                $videoLink = Puppeteer::getInstance()->getVideoLink($video['video_content']);
                $name = substr(md5(round(microtime(true)*10000).uniqid()),-20);
                $filePath = runtime_path('baokuan/'.date('ymd').'/'.$name.'.mp4');
                Common::mkdirs(dirname($filePath));
                $res = file_put_contents($filePath,file_get_contents($videoLink));
                if($res==false){
                    throw new IndexException(4020,'download video fail');
                }
                if(is_file($videoLink)){
                    unlink($videoLink);
                }
                $res = TencentCos::getInstance()->uploadLocalFile($filePath,'baokuan');
                $video['video_url'] = 'https://'.$res['Location'];
                unlink($filePath);
            }catch (\Throwable $e){
                $video->status = 2;
                $video->message = $e->getCode()==4020?$e->getMessage():'获取视频失败';
                $video->save();
                throw $e;
            }
        }

        if(empty($video['video_url'])){
            $video->status = 2;
            $video->message = '视频url不存在';
            $video->save();
            throw new IndexException(4020,'视频url不存在');
        }

        $res = TencentAsr::getInstance()->createRecTask($video['video_url']);

        $result = [];
        $startTime = time();
        while (true){
            $result = TencentAsr::getInstance()->describeTaskStatus($res['Data']['TaskId']);
            if(!empty($result['Data']['Status']) && $result['Data']['Status']==2){
                if(!empty($result['Data']['Result'])){
                    $content = trim(mb_substr($result['Data']['Result'],18));
                    $content = preg_replace(['/\[[\d|,|:|.]+\]/'],'',$content);
                    if(mb_strlen($content)<300 || mb_strlen($content)>6000 ){
                        $video->content = $content;
                        $video->status = 2;
                        $video->message = '视频字幕文字要在300-6000之间';
                        $video->save();
                    }else{
                        $video->content = $content;
                        $video->message = 'AI分析中...';
                        $video->save();

                        $this->submitData($video,$content);
                    }
                }

                return [$res,$result];
            }elseif(!empty($result['Data']['Status']) && $result['Data']['Status']==3){
                $video->status = 2;
                $video->message = '视频分析失败';
                $video->save();

                return [$res,$result];
            }

            if((time()-$startTime)>180){
                $video->status = 2;
                $video->message = '视频分析超时';
                $video->save();

                throw new IndexException(4020,'视频分析超时');
            }
        }
        return [$res,$result];
    }

    protected function submitData($video,$content)
    {
        $parts = [];
        try{
            //用户ai分段
            $parts = Common::aiContentPartsToUser($content);
            //$parts = Common::contentBatchPart($content);
        }catch (IndexException $e){
            if($e->getCode()==4049 || strpos($e->getMessage(),'敏感词')!==false){
                $video->status = 3;
                $video->message = $e->getMessage();
                $video->save();
                throw new IndexException(4020,$e->getMessage());
            }
        }

        if(empty($parts)){
            $video->content = $content;
            $video->status = 2;
            $video->message = 'AI分析失败,请稍后再试';
            $video->save();

            throw new IndexException(4020,'AI分析失败,请稍后再试');
        }

        //分段分析和字幕
        list($parts,$subTitles) = partsAnalyze($parts);

        $video->content = $content;
        $video->part_content = json_encode(array_values($parts),256);
        $video->subtitle = json_encode($subTitles,256);
        $video->status = 1;
        $video->message = 'AI分析成功';
        $video->save();

        return true;
    }

    // 消费失败回调
    /*
    $package = [
        'id' => 1357277951, // 消息ID
        'time' => 1709170510, // 消息时间
        'delay' => 0, // 延迟时间
        'attempts' => 2, // 消费次数
        'queue' => 'send-mail', // 队列名
        'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
        'max_attempts' => 5, // 最大重试次数
        'error' => '错误信息' // 错误信息
    ]
    */
    public function onConsumeFailure(\Throwable $e, $package)
    {
//        echo "consume failure\n";
//        echo $e->getMessage() . "\n";
//        // 无需反序列化
//        var_export($package);

        RedisQueue::getInstance()->saveQueue($this->queue,$package['data'],['error'=>$e->getMessage()]);
    }

}